package org.x.user.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.x.common.config.BusinessException;
import org.x.user.dto.AclQueryDTO;
import org.x.user.dto.CreateAclDTO;
import org.x.user.dto.UpdateAclDTO;
import org.x.user.entity.*;
import org.x.user.mapper.SysMenuMapper;
import org.x.user.mapper.SysRoleAclMapper;
import org.x.user.mapper.SysUserMapper;
import org.x.user.service.ISysAclService;
import org.x.user.mapper.SysAclMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.x.user.vo.AclInfoVO;
import org.x.user.vo.AclVO;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Service
public class SysAclServiceImpl extends ServiceImpl<SysAclMapper, SysAclEntity> implements ISysAclService {
    @Autowired
    private SysAclMapper sysAclMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleAclMapper sysRoleAclMapper;

    /**
     * 创建权限
     *
     * @param aclDTO 权限信息
     * @return 权限信息
     */
    @Transactional
    @Override
    public AclVO createAcl(CreateAclDTO aclDTO) {
        SysAclEntity sysAclEntity = new SysAclEntity();
        sysAclEntity.setName(aclDTO.getName());
        sysAclEntity.setCode(aclDTO.getCode());
        sysAclEntity.setType(aclDTO.getType());
        sysAclEntity.setUrl(aclDTO.getUrl());
        sysAclEntity.setIsDelete(0);
        //根据当前登录人设置创建人
        sysAclEntity.setCreatedBy(StpUtil.getLoginIdAsString());
        sysAclEntity.setCreatedTime(new Date());
        //校验权限码的唯一性
        SysAclEntity sysAclEntity1 = sysAclMapper.selectOneByQuery(new QueryWrapper()
                .select(SysAclEntity::getId)
                .eq(SysAclEntity::getCode, aclDTO.getCode()));
        if (sysAclEntity1 != null) {
            throw new BusinessException("权限码已存在");
        }
        //保存权限
        sysAclMapper.insert(sysAclEntity);
        //关联菜单sys_menu
        if(aclDTO.getType()==2){
            SysMenuEntity sysMenuEntity = sysMenuMapper.selectOneById(aclDTO.getMenuId());
            sysMenuEntity.setAclId(sysAclEntity.getId());
            sysMenuMapper.update(sysMenuEntity);
        }
        //返回权限ID
        AclVO aclVO = new AclVO();
        aclVO.setAclId(sysAclEntity.getId());
        return aclVO;
    }
    /**
     * 更新权限
     *
     * @param updateAclDTO 权限信息
     * @return 是否成功
     */
    @Transactional
    @Override
    public AclVO updateAcl(UpdateAclDTO updateAclDTO) {
        SysAclEntity sysAclEntity = sysAclMapper.selectOneById(updateAclDTO.getAclId());
        //校验权限点的存在性
        if(sysAclEntity==null){
            throw new BusinessException("权限点不存在");
        }
        //更新权限点信息
        BeanUtils.copyProperties(updateAclDTO,sysAclEntity);
        sysAclEntity.setUpdatedBy(StpUtil.getLoginIdAsString());
        sysAclEntity.setUpdatedTime(new Date());
        sysAclMapper.update(sysAclEntity);
        //更新菜单关联
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.select(SysMenuEntity::getId)
                .eq(SysMenuEntity::getAclId,sysAclEntity.getId());
        SysMenuEntity sysMenuEntity = sysMenuMapper.selectOneByQuery(queryWrapper);
        if (sysMenuEntity!=null){
            sysMenuEntity.setAclId(sysAclEntity.getId());
            sysMenuMapper.update(sysMenuEntity);
        }
        AclVO aclVO = new AclVO();
        aclVO.setAclId(sysAclEntity.getId());
        return aclVO;
    }
    /**
     * 删除权限
     *
     * @param id 删除权限信息
     * @return aclId
     */
    @Transactional
    @Override
    public AclVO deleteAcl(Long id) {
        //校验权限点存在性
        SysAclEntity sysAclEntity = sysAclMapper.selectOneById(id);
        if(sysAclEntity==null){
            throw new BusinessException("权限点不存在");
        }
        //校验未关联角色
        SysRoleAclEntity sysRoleAclEntity = sysRoleAclMapper.selectOneByQuery(new QueryWrapper()
                .select(SysRoleAclEntity::getRoleId)
                .eq(SysRoleAclEntity::getAclId, id));
        if(sysRoleAclEntity!=null){
            throw new BusinessException("权限点已关联角色");
        }
        //删除权限点
        sysAclMapper.deleteById(id);
        //清理菜单关联
        if(sysAclEntity.getType()==2){
            SysMenuEntity sysMenuEntity = sysMenuMapper.selectOneById(sysAclEntity.getId());
            sysMenuMapper.deleteById(sysMenuEntity.getId());
        }

        AclVO aclVO = new AclVO();
        aclVO.setAclId(sysAclEntity.getId());
        return aclVO;
    }
    /**
     * 查询权限点
     *
     * @param aclQueryDTO 查询权限点信息
     * @return 权限点列表
     */
    @Override
    public Page<AclInfoVO> pageList(AclQueryDTO aclQueryDTO) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if(aclQueryDTO.getName() != null){
            queryWrapper.like(SysAclEntity::getName, aclQueryDTO.getName());
        }
        if(aclQueryDTO.getCode() != null){
            queryWrapper.like(SysAclEntity::getCode, aclQueryDTO.getCode());
        }
        if(aclQueryDTO.getType() != null){
            queryWrapper.eq(SysAclEntity::getType, aclQueryDTO.getType());
        }
        Page<SysAclEntity> paginate = sysAclMapper.paginate(aclQueryDTO.getPage(), aclQueryDTO.getSize(), queryWrapper);
        List<SysAclEntity> records = paginate.getRecords();
        Set<Long> aclSet = records.stream().map(SysAclEntity::getId).collect(Collectors.toSet());
        QueryWrapper queryWrapper1 = new QueryWrapper();
        queryWrapper1.in(SysAclEntity::getId, aclSet);
        List<SysAclEntity> acls = sysAclMapper.selectListByQuery(queryWrapper1);

        //将paginate转换成page<AclInfoVO>
        Page<AclInfoVO> page = new Page<>();
        List<AclInfoVO> list = new LinkedList<>();
        records.forEach(record->{
            AclInfoVO aclInfoVO = new AclInfoVO();
            BeanUtils.copyProperties(record, aclInfoVO);
            aclInfoVO.setCreateTime(record.getCreatedTime());
            if(aclInfoVO.getType()==2){
                SysMenuEntity sysMenuEntity = sysMenuMapper.selectOneByQuery(new QueryWrapper()
                        .select(SysMenuEntity::getId)
                        .eq(SysMenuEntity::getAclId, aclInfoVO.getId()));
                if (sysMenuEntity != null) {
                    aclInfoVO.setMenuId(sysMenuEntity.getId());
                } else {
                    aclInfoVO.setMenuId(null);
                }
            }
            list.add(aclInfoVO);
        });
        page.setRecords(list);
        page.setTotalRow(paginate.getTotalRow());
        page.setTotalPage(paginate.getTotalPage());
        page.setPageNumber(paginate.getPageNumber());
        page.setPageSize(paginate.getPageSize());
        return page;
    }

    /**
     *查看权限点详情
     */
    @Override
    public SysAclEntity getDetail(Long id) {
        SysAclEntity sysAclEntity = sysAclMapper.selectOneById(id);
        return sysAclEntity;
    }

}